package com.conversationboard.view;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;

import com.conversationboard.cache.newanswers.NewAnswersThread;
import com.conversationboard.config.Configuration;
import com.conversationboard.formatter.DateFormatter;
import com.conversationboard.model.Board;
import com.conversationboard.model.Boards;
import com.conversationboard.model.Role;
import com.conversationboard.model.User;
import com.conversationboard.model.preferences.SiteNewPostsViewInfo;

public class ThreadListDisplay {

	public static String display(Board board, List<NewAnswersThread> threads, String userId, OrderedBy orderedBy) throws SQLException {

		StringBuilder buffer = new StringBuilder();
		boolean isSiteNewPosts = (board == null);
		Date today = new Date();

		User user = User.get(userId);
		Role role = user.getRole();
		boolean admin = false;

		Map<Integer, SiteNewPostsViewInfo> viewInfo = null;

		if (isSiteNewPosts && user.isLoggedIn()) {
			viewInfo = user.getPreferences().getSiteNewPostsViewInfo();
		}

		if ((role == Role.SiteAdmin) || ((!isSiteNewPosts) && user.isBoardAdmin(board.getBoardId()))) {
			admin = true;
		}

		buffer.append("<ul>");

		MutableDateTime date = new MutableDateTime(new Date());

		for (NewAnswersThread thread : threads) {

			Board threadBoard = Boards.getBoard(thread.getBoardId());

			if (threadBoard.isPrivateBoard() && (!user.isMemberOfBoard(threadBoard.getBoardId()))) {
				continue;
			}

			MutableDateTime threadDate;

			if ((orderedBy == OrderedBy.LAST_UPDATED) || (orderedBy == OrderedBy.ALPHABETICAL)) {
				threadDate = new MutableDateTime(thread.getLastUpdated());
			} else {
				threadDate = new MutableDateTime(thread.getTimestamp());
			}

			threadDate.setZone(DateTimeZone.forTimeZone(user.getPreferences().getTimeZone()));

			int day = threadDate.getDayOfMonth();

			/* Don't display the date change notifier if they're alphabetically ordered as it won't make sense */
			
			if ((date.getDayOfMonth() != day) && (orderedBy != OrderedBy.ALPHABETICAL)) {
				buffer.append("<h3>Last on " + DateFormatter.prettyPrint(threadDate.toDate(), user) + "</h3>");
			}

			date = threadDate;

			if (thread.isDeleted() && (!admin)) {
				continue;
			}

			if (user.getPreferences().isHidePolls() && thread.isPoll()) {
				continue;
			}

			/* Display Site New Answers in colours, and potentially skip this thread, if you've decided that way in preferences */

			String colourOverrideStyle = "";

			if (isSiteNewPosts && user.isLoggedIn()) {
				if (viewInfo != null) {
					SiteNewPostsViewInfo info = viewInfo.get(thread.getBoardId());

					if (info != null) {

						if (info.isHide()) {
							continue;
						}

						if (!info.getColour().equals("")) {
							colourOverrideStyle = "style='color: " + info.getColour() + "'";
						}
						
					}
				}
			}

			/* Display an empty bullet if the thread has posts since you last looked at it, or if you've never looked at it at all (latest message ID will be 0) */

			if (user.isLoggedIn()) {

				int latestMessageId = user.getMostRecentMessageId(thread.getBoardId(), thread.getThreadId());

				if ((thread.getLatestMessageId() > latestMessageId) && (latestMessageId != 0)) {
					buffer.append("<li class=\"thread updated\">");
				} else {
					buffer.append("<li class=\"thread\">");
				}

			} else {
				buffer.append("<li class=\"thread\">");
			}

			if (thread.isUnanswered()) {
				buffer.append("<span class='unansweredthread'>");
			}

			if (thread.isDeleted()) {
				if (!admin) {
					continue;
				} else {
					buffer.append("<span class='deletedthread'>");
				}
			}

			if (thread.isLocked()) {
				buffer.append("[LOCKED] ");
			}

			if (!thread.isWorksafe()) {
				buffer.append("<span class='notworksafe'>[NOT WORKSAFE] ");
			}

			buffer.append("<a " + colourOverrideStyle + " href='" + Configuration.getInstance().getRoot() + "/ThreadSelectedControllerServlet?boardid=");
			buffer.append(thread.getBoardId());
			buffer.append("&amp;threadid=");
			buffer.append(thread.getThreadId());
			buffer.append("#unread'>");
			buffer.append(thread.getTitle());
			buffer.append("</a>");

			if (!user.getPreferences().isHideThreadInfo()) {

				SimpleDateFormat formatter = new SimpleDateFormat("MMMMMMMM yyyy");
				String year = formatter.format(thread.getTimestamp());

				buffer.append(" <span class=\"threaddata\">[Started by ");
				buffer.append(thread.getCreatorId());
				buffer.append(" in " + year);
				buffer.append(", last updated ");
				buffer.append(DateFormatter.prettyPrintTime(thread.getLastUpdated(), user, false, true));

				if (!user.getPreferences().isHideLastUpdatedBy()) {

					if ((thread.getLastUpdatedByDisplayName() != null) && (!thread.getLastUpdatedByDisplayName().trim().equals(""))) {
						buffer.append(" by <span class='threadlu'>");
						buffer.append(thread.getLastUpdatedByDisplayName());
						buffer.append("</span>");
					}
				}

				if (isSiteNewPosts) {
					buffer.append(" on <span class='threadlu'><a href='http://" + Configuration.getInstance().getDomainName() + Configuration.getInstance().getRoot() + "/NewAnswersControllerServlet?boardid=" + threadBoard.getBoardId() + "'>" + threadBoard.getName() + "</a></span>");
				}

				buffer.append("]</span>");
			}

			int recentMessages = thread.getNumberOfRecentMessages();

			if (recentMessages > 0) {
				buffer.append(" <span class='threadlu'>");
				buffer.append(recentMessages);

				if (recentMessages == 1) {
					buffer.append(" new answer");
				} else {
					buffer.append(" new answers");
				}

			}

			buffer.append("</span>");

			if (thread.isPoll()) {
				SimpleDateFormat formatter = new SimpleDateFormat("MMMMMMMM dd");
				if (!thread.getPollClosingDate().before(new Date())) {
					buffer.append(" <span class='pollthread'>POLL closes: " + formatter.format(thread.getPollClosingDate()) + " (in " + DateFormatter.prettyPrintFutureTime(thread.getPollClosingDate(), today, user.getPreferences().getTimeZone()) + ")</span> ");
				} else {
					buffer.append(" <span class='pollthread'>POLL results</span> ");
				}
			}

			if (thread.isDeleted()) {
				buffer.append("</span>");
			}

			if (!thread.isWorksafe()) {
				buffer.append("</span>");
			}

			if (thread.isUnanswered()) {
				buffer.append("</span>");
			}

			/* If you're a site admin, or you administer this board, then display the admin links */

			if (admin) {
				buffer.append("<br />");
				ThreadListAdminLinksDisplay.includeAdminLinks(buffer, thread.getBoardId(), thread.getThreadId(), user, "adminlinks", "adminlink");
			}

			buffer.append("</li>");
		}

		buffer.append("</ul>");

		return buffer.toString();

	}

}
